/*
观察者模式（Observer Pattern）是一种行为型设计模式，它定义了一种一对多的依赖关系，使得多个观察者对象可以同时监听一个主题对象的状态变化。
当主题对象的状态发生变化时，会自动通知所有的观察者对象，并调用它们的更新方法，从而实现了对象之间的解耦。

观察者模式的核心角色包括：

1. 主题（Subject）：它是被观察的对象，它维护了一组观察者对象，并提供了添加、删除和通知观察者的方法。
2. 观察者（Observer）：它定义了一个更新方法，用于接收主题对象的通知，并进行相应的处理。
3. 具体主题（ConcreteSubject）：它是主题的具体实现，维护了一组观察者对象，并在状态发生变化时通知观察者。
4. 具体观察者（ConcreteObserver）：它是观察者的具体实现，实现了更新方法，用于接收主题对象的通知并进行相应的处理。

下面是一个使用观察者模式的C语言例程：
*/

#include <stdio.h>
#include <stdlib.h>

// 观察者接口
typedef struct {
    void (*update)(void *observer, int state);
} Observer;

// 具体观察者
typedef struct {
    Observer observer;
    int state;
} ConcreteObserver;

void update(void *observer, int state) {
    ConcreteObserver *concreteObserver = (ConcreteObserver *)observer;
    concreteObserver->state = state;
    printf("Observer state updated: %d\n", concreteObserver->state);
}

Observer *createObserver() {
    Observer *observer = (Observer *)malloc(sizeof(Observer));
    observer->update = update;
    return observer;
}

void destroyObserver(Observer *observer) {
    free(observer);
}

// 主题接口
typedef struct {
    void (*attach)(void *subject, Observer *observer);
    void (*detach)(void *subject, Observer *observer);
    void (*notify)(void *subject);
} Subject;

// 具体主题
typedef struct {
    Subject subject;
    Observer **observers;
    int count;
    int state;
} ConcreteSubject;

void attach(void *subject, Observer *observer) {
    ConcreteSubject *concreteSubject = (ConcreteSubject *)subject;
    concreteSubject->observers = (Observer **)realloc(concreteSubject->observers, (concreteSubject->count + 1) * sizeof(Observer *));
    concreteSubject->observers[concreteSubject->count] = observer;
    concreteSubject->count++;
}

void detach(void *subject, Observer *observer) {
    ConcreteSubject *concreteSubject = (ConcreteSubject *)subject;
    int i, j;
    for (i = 0; i < concreteSubject->count; i++) {
        if (concreteSubject->observers[i] == observer) {
            for (j = i; j < concreteSubject->count - 1; j++) {
                concreteSubject->observers[j] = concreteSubject->observers[j + 1];
            }
            concreteSubject->observers = (Observer **)realloc(concreteSubject->observers, (concreteSubject->count - 1) * sizeof(Observer *));
            concreteSubject->count--;
            break;
        }
    }
}

void notify(void *subject) {
    ConcreteSubject *concreteSubject = (ConcreteSubject *)subject;
    int i;
    for (i = 0; i < concreteSubject->count; i++) {
        concreteSubject->observers[i]->update(concreteSubject->observers[i], concreteSubject->state);
    }
}

Subject *createSubject() {
    Subject *subject = (Subject *)malloc(sizeof(Subject));
    subject->attach = attach;
    subject->detach = detach;
    subject->notify = notify;
    return subject;
}

void destroySubject(Subject *subject) {
    free(subject);
}

int main() {
    Subject *subject = createSubject();

    Observer *observer1 = createObserver();
    Observer *observer2 = createObserver();

    subject->attach(subject, observer1);
    subject->attach(subject, observer2);

    subject->notify(subject);

    subject->detach(subject, observer1);

    subject->notify(subject);

    destroyObserver(observer1);
    destroyObserver(observer2);
    destroySubject(subject);

    return 0;
}

/*
在上面的例程中，首先定义了观察者接口Observer，其中包含了更新方法update。
然后，定义了具体观察者ConcreteObserver，它实现了更新方法。
在createObserver函数中，创建了观察者对象，并将更新方法设置为update。
接下来，定义了主题接口Subject，其中包含了添加、删除和通知观察者的方法。
然后，定义了具体主题ConcreteSubject，它实现了主题接口。
在attach函数中，添加了观察者对象。在detach函数中，删除了观察者对象。
在notify函数中，通知了所有的观察者对象。
在createSubject函数中，创建了主题对象，并将添加、删除和通知方法设置为相应的函数。
最后，在main函数中，创建了主题对象和观察者对象，并通过主题对象添加、删除和通知了观察者对象。

通过使用观察者模式，我们可以实现对象之间的解耦，主题对象和观察者对象之间只通过接口进行通信，而不直接依赖于具体的实现。
这样，在主题对象的状态发生变化时，只需要通知观察者对象即可，无需关心观察者对象的具体实现。
观察者模式可以用于实现事件驱动的系统，也可以用于实现发布-订阅模式。
*/